package handlers

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"net/http"

	"grpc-jwt-yonghurenzheng/v0/config"
	"grpc-jwt-yonghurenzheng/v0/models"

	"golang.org/x/crypto/bcrypt"
)

// 注册
func Register(w http.ResponseWriter, r *http.Request) {
	var user models.User
	if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
		http.Error(w, "请求数据错误", http.StatusBadRequest)
		return
	}

	// 密码加密
	hashed, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		http.Error(w, "密码加密失败", http.StatusInternalServerError)
		return
	}

	// 插入数据库
	_, err = config.DB.Exec("INSERT INTO users (username, password, email) VALUES (?, ?, ?)",
		user.Username, string(hashed), user.Email)
	if err != nil {
		http.Error(w, fmt.Sprintf("注册失败: %v", err), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(map[string]string{"message": "注册成功"})
}

// 统一 JSON 错误返回
func writeJSONError(w http.ResponseWriter, status int, msg string) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(status)
    json.NewEncoder(w).Encode(map[string]string{"error": msg})
}

// Login 登录接口
func Login(w http.ResponseWriter, r *http.Request) {
    // 只允许 POST
    if r.Method != http.MethodPost {
        writeJSONError(w, http.StatusMethodNotAllowed, "只允许 POST 方法")
        return
    }

    w.Header().Set("Content-Type", "application/json")

    // 解析请求 JSON
    var loginReq models.User
    if err := json.NewDecoder(r.Body).Decode(&loginReq); err != nil {
        writeJSONError(w, http.StatusBadRequest, "请求 JSON 数据错误: " + err.Error())
        return
    }

    if loginReq.Username == "" || loginReq.Password == "" {
        writeJSONError(w, http.StatusBadRequest, "用户名或密码不能为空")
        return
    }

    // 从数据库查询用户
    var user models.User
    var hashedPwd string
    err := config.DB.QueryRow("SELECT id, username, password, email FROM users WHERE username = ?", loginReq.Username).
        Scan(&user.ID, &user.Username, &hashedPwd, &user.Email)

    if err == sql.ErrNoRows {
        writeJSONError(w, http.StatusUnauthorized, "用户不存在")
        return
    } else if err != nil {
        writeJSONError(w, http.StatusInternalServerError, "查询数据库失败: "+err.Error())
        return
    }

    // 校验密码
    if err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(loginReq.Password)); err != nil {
        writeJSONError(w, http.StatusUnauthorized, "密码错误")
        return
    }

    // 登录成功
    json.NewEncoder(w).Encode(map[string]interface{}{
        "message":  "登录成功",
        "user_id":  user.ID,
        "username": user.Username,
        "email":    user.Email,
    })
}

// 注销用户
func DeleteUser(w http.ResponseWriter, r *http.Request) {
    var req struct {
        Username string `json:"username"`
    }

    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        http.Error(w, "请求数据错误", http.StatusBadRequest)
        return
    }

    // 先查询用户是否存在
    var userID int
    err := config.DB.QueryRow("SELECT id FROM users WHERE username = ?", req.Username).Scan(&userID)
    if err == sql.ErrNoRows {
        http.Error(w, "用户不存在", http.StatusNotFound)
        return
    } else if err != nil {
        http.Error(w, "查询数据库失败", http.StatusInternalServerError)
        return
    }

    // 如果有外键表（比如 addresses），可先删除子表，或者保证外键 ON DELETE CASCADE
    // 删除子表示例：
    _, err = config.DB.Exec("DELETE FROM addresses WHERE user_id = ?", userID)
    if err != nil {
        http.Error(w, "删除用户地址失败", http.StatusInternalServerError)
        return
    }

    // 删除用户
    _, err = config.DB.Exec("DELETE FROM users WHERE id = ?", userID)
    if err != nil {
        http.Error(w, "删除用户失败", http.StatusInternalServerError)
        return
    }

    json.NewEncoder(w).Encode(map[string]string{"message": "用户已注销"})
}